package controller

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"sort"
	"strconv"
	"subtitleAnalyser/model"
	"subtitleAnalyser/util"
)

// @Title  analyser
// @Description  字幕解释
// @Author  chen（陈锴）
// @Update  chen（陈锴）  2023-12-23
// @Reture subtitles reerrors
func Analyser(filePath string) (resubtitles model.Subtitles, reerrors []string) {
	// 打开文件
	file, err := os.Open(filePath)
	if err != nil {
		reerrors = append(reerrors, "无法打开文件，地址错误或文件错误")
		return
	}
	defer file.Close()

	// 按行读入文件
	buff := bufio.NewReader(file)

	// 字幕数组
	subtitles := make([]model.Subtitle, 0)
	// 错误数组
	errors := make([]string, 0)

	// 单个字幕
	subtitle := model.Subtitle{}

	// 自动机当前状态
	state := 0

	// 开始分析
	for i := 1; ; i++ {
		li, _, serr := buff.ReadLine()

		// 文件结束
		if serr == io.EOF {
			// 数据残缺
			if state != 0 {
				message := fmt.Sprintf("字幕文件第 %d 行：数据残缺\n", i)
				errors = append(errors, message)
			}
			break
		}

		// 行读取失败
		if serr != nil {
			message := fmt.Sprintf("字幕文件第 %d 行：读取失败\n", i)
			errors = append(errors, message)
			continue
		}

		// 清理每行后方多余字符
		index := len(li) - 1
		for ; index >= 0; index-- {
			if li[index] == '\r' || li[index] == '\n' || li[index] == ' ' {
				continue
			}
			break
		}
		// 截取字符串
		line := string(li[0: index + 1])

		// 状态 0
		if state == 0 {
			// 0 -> e 0
			// 允许空行
			if line == "" {
				continue
			}

			// 获取字幕编号
			id, ferr := strconv.Atoi(line)
			if ferr != nil || id < 0 {
				message := fmt.Sprintf("字幕文件第 %d 行：编号格式错误\n", i)
				errors = append(errors, message)
				// 损坏
				id = -1
			}

			// 记录
			subtitle.Id = id
			// 0 -> id 1
			// 状态转移
			state++
		// 状态 1
		} else if state == 1 {
			start, end, ferr := util.GetTime(line)
			if ferr != nil {
				message := fmt.Sprintf("字幕文件第 %d 行：", i) + ferr.Error() + "\n"
				errors = append(errors, message)
				// 损坏
				subtitle.Id = -1
			}

			// 记录
			subtitle.StartTime = start
			subtitle.EndTime = end
			// 1 -> time 2
			// 状态转移
			state++
		// 状态 2
		} else if state == 2 {
			// 保存字幕
			if line !=  "" {
				subtitle.Content = subtitle.Content + line + "\n"
				continue
			}
			// 字幕未损坏 损坏则不保留
			if subtitle.Id != -1 {
				// 遇到空行 将字幕保存
				subtitles = append(subtitles, subtitle)
			}
			// 更新字幕单元
			subtitle = model.Subtitle{}
			// 2 -> empty 0
			// 状态转移
			state = 0
		}
	}

	// 字幕排序
	sort.Sort(model.Subtitles(subtitles))

	// 字幕时间是否重叠
	for i := 1; i < len(subtitles); i++ {
		if subtitles[i - 1].EndTime <= subtitles[i].StartTime {
			continue
		}
		// 时间压缩
		subtitles[i - 1].EndTime = subtitles[i].StartTime
	}

	resubtitles = subtitles
	reerrors = errors
	return
}